﻿using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.VisualBasic;
using WirelessAccessPoint.Core;
using WirelessAccessPoint.DataAnnotations;
using WirelessAccessPoint.InteropServices;
using WirelessAccessPoint.Resources;

namespace WirelessAccessPoint.Model
{
    /// <summary>
    /// Hosted Networkを表します。
    /// </summary>
    public class HostedNetwork : ModelBase
    {
        private WLAN_HOSTED_NETWORK_STATE? hostedNetworkState;
        private Guid? deviceID;
        private string bssid;
        private uint? channelFrequency;
        private DOT11_PHY_TYPE? phyType;
        private string ssid;
        private uint? maxNumberOfPeers;
        private string passPhrase;
        private DOT11_AUTH_ALGORITHM? authAlgorithm;
        private DOT11_CIPHER_ALGORITHM? cipherAlgorithm;

        #region プロパティ

        /// <summary>
        /// 状態を設定または取得します。
        /// </summary>
        public WLAN_HOSTED_NETWORK_STATE? HostedNetworkState
        {
            get { return this.hostedNetworkState; }
            set
            {
                if (value != this.hostedNetworkState)
                {
                    this.hostedNetworkState = value;
                    this.OnPropertyChanged(() => this.HostedNetworkState);
                    this.OnPropertyChanged(() => this.HostedNetworkStateString);
                }
            }
        }

        /// <summary>
        /// デバイスIDを設定または取得します。
        /// </summary>
        public Guid? DeviceID
        {
            get { return this.deviceID; }
            set
            {
                if (value != this.deviceID)
                {
                    this.deviceID = value;
                    this.OnPropertyChanged(() => this.DeviceID);
                }
            }
        }

        /// <summary>
        /// BSSIDを設定または取得します。
        /// </summary>
        public string BSSID
        {
            get { return this.bssid; }
            set
            {
                if (value != this.bssid)
                {
                    this.bssid = value;
                    this.OnPropertyChanged(() => this.BSSID);
                }
            }
        }

        /// <summary>
        /// 無線チャネルを設定または取得します。
        /// </summary>
        public uint? ChannelFrequency
        {
            get { return this.channelFrequency; }
            set
            {
                if (value != this.channelFrequency)
                {
                    this.channelFrequency = value;
                    this.OnPropertyChanged(() => this.ChannelFrequency);
                }
            }
        }

        /// <summary>
        /// 通信方式を設定または取得します。
        /// </summary>
        public DOT11_PHY_TYPE? PhyType
        {
            get { return this.phyType; }
            set
            {
                if (value != this.phyType)
                {
                    this.phyType = value;
                    this.OnPropertyChanged(() => this.PhyType);
                    this.OnPropertyChanged(() => this.PhyTypeString);
                }
            }
        }

        /// <summary>
        /// SSIDを設定または取得します。
        /// </summary>
        [Display(ResourceType = typeof(LabelResource), Name = "SSIDLabel")]
        [InputConverter(VbStrConv.Narrow)]
        [RegexInputTextFilter("^[\x21-\x7F]+$")]
        [Required(ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "RequiredMessage")]
        [StringLength(32, MinimumLength = 1, ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "StringLengthMessage")]
        [RegularExpression("^[\x21-\x7F]+$", ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "ASCIIWithoutSPRegexMessage")]
        public string SSID
        {
            get { return this.ssid; }
            set
            {
                if (value != this.ssid)
                {
                    this.ssid = value;
                    this.OnPropertyChanged(() => this.SSID);
                }
            }
        }

        /// <summary>
        /// 最大接続数を設定または取得します。
        /// </summary>
        public uint? MaxNumberOfPeers
        {
            get { return this.maxNumberOfPeers; }
            set
            {
                if (value != this.maxNumberOfPeers)
                {
                    this.maxNumberOfPeers = value;
                    this.OnPropertyChanged(() => this.MaxNumberOfPeers);
                }
            }
        }

        /// <summary>
        /// パスフレーズを設定または取得します。
        /// </summary>
        [Display(ResourceType = typeof(LabelResource), Name = "PassPhraseLabel")]
        [InputConverter(VbStrConv.Narrow)]
        [RegexInputTextFilter("^[\x21-\x7F]+$")]
        [Required(ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "RequiredMessage")]
        [StringLength(64, MinimumLength = 8, ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "StringLengthMessage")]
        [RegularExpression("^[\x21-\x7F]+$", ErrorMessageResourceType = typeof(MessageResource), ErrorMessageResourceName = "ASCIIWithoutSPRegexMessage")]
        public string PassPhrase
        {
            get { return this.passPhrase; }
            set
            {
                if (value != this.passPhrase)
                {
                    this.passPhrase = value;
                    this.OnPropertyChanged(() => this.PassPhrase);
                }
            }
        }

        /// <summary>
        /// 認証方式を設定または取得します。
        /// </summary>
        public DOT11_AUTH_ALGORITHM? AuthAlgorithm
        {
            get { return this.authAlgorithm; }
            set
            {
                if (value != this.authAlgorithm)
                {
                    this.authAlgorithm = value;
                    this.OnPropertyChanged(() => this.AuthAlgorithm);
                    this.OnPropertyChanged(() => this.AuthAlgorithmString);
                }
            }
        }

        /// <summary>
        /// 暗号方式を設定または取得します。
        /// </summary>
        public DOT11_CIPHER_ALGORITHM? CipherAlgorithm
        {
            get { return this.cipherAlgorithm; }
            set
            {
                if (value != this.cipherAlgorithm)
                {
                    this.cipherAlgorithm = value;
                    this.OnPropertyChanged(() => this.CipherAlgorithm);
                    this.OnPropertyChanged(() => this.CipherAlgorithmString);
                }
            }
        }

        #endregion

        #region 表示用プロパティ

        /// <summary>
        /// 状態の文字列表現を取得します。
        /// </summary>
        public string HostedNetworkStateString
        {
            get { return this.HostedNetworkState.ToLabel<WlanHostedNetworkStateResource>(); }
        }

        /// <summary>
        /// 通信方式の文字列表現を取得します。
        /// </summary>
        public string PhyTypeString
        {
            get { return this.PhyType.ToLabel<Dot11PhyTypeResource>(); }
        }

        /// <summary>
        /// 認証方式の文字列表現を取得します。
        /// </summary>
        public string AuthAlgorithmString
        {
            get { return this.AuthAlgorithm.ToLabel<Dot11AuthAlgorithmResource>(); }
        }

        /// <summary>
        /// 暗号方式の文字列表現を取得します。
        /// </summary>
        public string CipherAlgorithmString
        {
            get { return this.CipherAlgorithm.ToLabel<Dot11CipherAlgorithmResource>(); }
        }

        #endregion
    }
}
